home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / PATTERN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-19  |  41.3 KB  |  2,217 lines  |  [TEXT/CWIE]

  1. /**************************************************************************
  2. *                pattern.c
  3. *
  4. *  This module implements texturing functions that return a value to be
  5. *  used in a pigment or normal.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. /*
  26.  * Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
  27.  * "An Image Synthesizer" By Ken Perlin.
  28.  * Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley).
  29.  */
  30.  
  31. #include "frame.h"
  32. #include "vector.h"
  33. #include "povproto.h"
  34. #include "matrices.h"
  35. #include "pattern.h"
  36. #include "texture.h"
  37. #include "image.h"
  38. #include "txttest.h"
  39. #include "colour.h"
  40.  
  41.  
  42.  
  43. /*****************************************************************************
  44. * Local preprocessor defines
  45. ******************************************************************************/
  46.  
  47.  
  48. /*****************************************************************************
  49. * Static functions
  50. ******************************************************************************/
  51.  
  52. static DBL agate PARAMS((VECTOR EPoint, TPATTERN *TPat));
  53. static DBL brick PARAMS((VECTOR EPoint, TPATTERN *TPat));
  54. static DBL checker PARAMS((VECTOR EPoint));
  55. static DBL crackle PARAMS((VECTOR EPoint));
  56. static DBL gradient PARAMS((VECTOR EPoint, TPATTERN *TPat));
  57. static DBL granite PARAMS((VECTOR EPoint));
  58. static DBL leopard PARAMS((VECTOR EPoint));
  59. static DBL mandel PARAMS((VECTOR EPoint, TPATTERN *TPat));
  60. static DBL marble PARAMS((VECTOR EPoint, TPATTERN *TPat));
  61. static DBL onion PARAMS((VECTOR EPoint));
  62. static DBL radial PARAMS((VECTOR EPoint));
  63. static DBL spiral1 PARAMS((VECTOR EPoint, TPATTERN *TPat));
  64. static DBL spiral2 PARAMS((VECTOR EPoint, TPATTERN *TPat));
  65. static DBL wood PARAMS((VECTOR EPoint, TPATTERN *TPat));
  66. static DBL hexagon PARAMS((VECTOR EPoint));
  67. static long PickInCube PARAMS((VECTOR tv, VECTOR p1));
  68.  
  69. static DBL ripples_pigm PARAMS((VECTOR EPoint, TPATTERN *TPat));
  70. static DBL waves_pigm  PARAMS((VECTOR EPoint, TPATTERN *TPat));
  71. static DBL dents_pigm  PARAMS((VECTOR EPoint));
  72. static DBL wrinkles_pigm PARAMS((VECTOR EPoint));
  73. static DBL quilted_pigm PARAMS((VECTOR EPoint, TPATTERN *TPat));
  74. static TURB *Search_For_Turb PARAMS((WARP *Warps));
  75. /* static TURB *Copy_Turb PARAMS((TURB *Old));   Unused function [AED] */
  76.  
  77.  
  78.  
  79. /*****************************************************************************
  80. *
  81. * FUNCTION
  82. *
  83. *   agate
  84. *
  85. * INPUT
  86. *
  87. *   EPoint -- The point in 3d space at which the pattern is evaluated.
  88. *   TPat   -- Texture pattern struct
  89. *
  90. * OUTPUT
  91. *
  92. * RETURNS
  93. *
  94. *   DBL value in the range 0.0 to 1.0
  95. *
  96. * AUTHOR
  97. *
  98. *   POV-Ray Team
  99. *
  100. * DESCRIPTION
  101. *
  102. * CHANGES
  103. *   Oct 1994    : adapted from agate pigment by [CY]
  104. *
  105. ******************************************************************************/
  106.  
  107. static DBL agate (EPoint, TPat)
  108. VECTOR EPoint;
  109. TPATTERN *TPat;
  110. {
  111.   register DBL noise, turb_val;
  112.   TURB* Turb;
  113.  
  114.   Turb=Search_For_Turb(TPat->Warps);
  115.  
  116.   turb_val = TPat->Vals.Agate_Turb_Scale * Turbulence(EPoint,Turb);
  117.  
  118.   noise = 0.5 * (cycloidal(1.3 * turb_val + 1.1 * EPoint[Z]) + 1.0);
  119.  
  120.   if (noise < 0.0)
  121.   {
  122.     noise = 0.0;
  123.   }
  124.   else
  125.   {
  126.     noise = min(1.0, noise);
  127.     noise = pow(noise, 0.77);
  128.   }
  129.  
  130.   return(noise);
  131. }
  132.  
  133.  
  134. /*****************************************************************************
  135. *
  136. * FUNCTION
  137. *
  138. *   brick
  139. *
  140. * INPUT
  141. *
  142. *   EPoint -- The point in 3d space at which the pattern
  143. *   is evaluated.
  144. *   TPat   -- Texture pattern struct
  145. *   
  146. * OUTPUT
  147. *   
  148. * RETURNS
  149. *
  150. *   DBL value exactly 0.0 or 1.0
  151. *   
  152. * AUTHOR
  153. *
  154. *   Dan Farmer
  155. *   
  156. * DESCRIPTION
  157. *
  158. * CHANGES
  159. *   Oct 1994    : adapted from pigment by [CY]
  160. *
  161. ******************************************************************************/
  162.  
  163. static DBL brick (EPoint, TPat)
  164. VECTOR EPoint;
  165. TPATTERN *TPat;
  166. {
  167.   int ibrickx, ibricky, ibrickz;
  168.   DBL brickheight, brickwidth, brickdepth;
  169.   DBL brickmortar, mortarheight, mortarwidth, mortardepth;
  170.   DBL brickx, bricky, brickz;
  171.   DBL x, y, z, fudgit;
  172.  
  173.   fudgit=Small_Tolerance+TPat->Vals.Brick.Mortar;
  174.  
  175.   x =  EPoint[X]+fudgit;
  176.   y =  EPoint[Y]+fudgit;
  177.   z =  EPoint[Z]+fudgit;
  178.  
  179.   brickwidth  = TPat->Vals.Brick.Size[X];
  180.   brickheight = TPat->Vals.Brick.Size[Y];
  181.   brickdepth  = TPat->Vals.Brick.Size[Z];
  182.   brickmortar = (DBL)TPat->Vals.Brick.Mortar;
  183.  
  184.   mortarwidth  = brickmortar / brickwidth;
  185.   mortarheight = brickmortar / brickheight;
  186.   mortardepth  = brickmortar / brickdepth;
  187.  
  188.   /* 1) Check mortar layers in the X-Z plane (ie: top view) */
  189.  
  190.   bricky = y / brickheight;
  191.   ibricky = (int) bricky;
  192.   bricky -= (DBL) ibricky;
  193.  
  194.   if (bricky < 0.0)
  195.   {
  196.     bricky += 1.0;
  197.   }
  198.  
  199.   if (bricky <= mortarheight)
  200.   {
  201.     return(0.0);
  202.   }
  203.  
  204.   bricky = (y / brickheight) * 0.5;
  205.   ibricky = (int) bricky;
  206.   bricky -= (DBL) ibricky;
  207.  
  208.   if (bricky < 0.0)
  209.   {
  210.     bricky += 1.0;
  211.   }
  212.  
  213.  
  214.   /* 2) Check ODD mortar layers in the Y-Z plane (ends) */
  215.  
  216.   brickx = (x / brickwidth);
  217.   ibrickx = (int) brickx;
  218.   brickx -= (DBL) ibrickx;
  219.  
  220.   if (brickx < 0.0)
  221.   {
  222.     brickx += 1.0;
  223.   }
  224.  
  225.   if ((brickx <= mortarwidth) && (bricky <= 0.5))
  226.   {
  227.     return(0.0);
  228.   }
  229.  
  230.   /* 3) Check EVEN mortar layers in the Y-Z plane (ends) */
  231.  
  232.   brickx = (x / brickwidth) + 0.5;
  233.   ibrickx = (int) brickx;
  234.   brickx -= (DBL) ibrickx;
  235.  
  236.   if (brickx < 0.0)
  237.   {
  238.     brickx += 1.0;
  239.   }
  240.  
  241.   if ((brickx <= mortarwidth) && (bricky > 0.5))
  242.   {
  243.     return(0.0);
  244.   }
  245.  
  246.   /* 4) Check ODD mortar layers in the Y-X plane (facing) */
  247.  
  248.   brickz = (z / brickdepth);
  249.   ibrickz = (int) brickz;
  250.   brickz -= (DBL) ibrickz;
  251.  
  252.   if (brickz < 0.0)
  253.   {
  254.     brickz += 1.0;
  255.   }
  256.  
  257.   if ((brickz <= mortardepth) && (bricky > 0.5))
  258.   {
  259.     return(0.0);
  260.   }
  261.  
  262.   /* 5) Check EVEN mortar layers in the X-Y plane (facing) */
  263.  
  264.   brickz = (z / brickdepth) + 0.5;
  265.   ibrickz = (int) brickz;
  266.   brickz -= (DBL) ibrickz;
  267.  
  268.   if (brickz < 0.0)
  269.   {
  270.     brickz += 1.0;
  271.   }
  272.  
  273.   if ((brickz <= mortardepth) && (bricky <= 0.5))
  274.   {
  275.     return(0.0);
  276.   }
  277.  
  278.   /* If we've gotten this far, color me brick. */
  279.  
  280.   return(1.0);
  281. }
  282.  
  283.  
  284. /*****************************************************************************
  285. *
  286. * FUNCTION
  287. *
  288. *   checker
  289. *
  290. * INPUT
  291. *
  292. *   EPoint -- The point in 3d space at which the pattern
  293. *   is evaluated.
  294. *
  295. * OUTPUT
  296. *
  297. * RETURNS
  298. *
  299. *   DBL value exactly 0.0 or 1.0
  300. *
  301. * AUTHOR
  302. *
  303. *   POV-Team
  304. *
  305. * DESCRIPTION
  306. *
  307. * CHANGES
  308. *   Oct 1994    : adapted from pigment by [CY]
  309. *
  310. ******************************************************************************/
  311.  
  312. static DBL checker (EPoint)
  313. VECTOR EPoint;
  314. {
  315.   int value;
  316.  
  317.   value = (int)(floor(EPoint[X]+Small_Tolerance) +
  318.                 floor(EPoint[Y]+Small_Tolerance) +
  319.                 floor(EPoint[Z]+Small_Tolerance));
  320.  
  321.   if (value & 1)
  322.   {
  323.     return (1.0);
  324.   }
  325.   else
  326.   {
  327.     return (0.0);
  328.   }
  329. }
  330.  
  331.  
  332.  
  333. /*****************************************************************************
  334. *
  335. * FUNCTION
  336. *
  337. *   crackle
  338. *
  339. * INPUT
  340. *
  341. *   EPoint -- The point in 3d space at which the pattern
  342. *   is evaluated.
  343. * OUTPUT
  344. *
  345. * RETURNS
  346. *
  347. *   DBL value in the range 0.0 to 1.0
  348. *
  349. * AUTHOR
  350. *
  351. *   Jim McElhiney
  352. *
  353. * DESCRIPTION
  354. *
  355. *   "crackle":
  356. *
  357. *   New colour function by Jim McElhiney,
  358. *     CompuServe 71201,1326, aka mcelhiney@acm.org
  359. *
  360. *   Large scale, without turbulence, makes a pretty good stone wall.
  361. *   Small scale, without turbulence, makes a pretty good crackle ceramic glaze.
  362. *   Highly turbulent (with moderate displacement) makes a good marble, solving
  363. *   the problem of apparent parallel layers in Perlin's method.
  364. *   2 octaves of full-displacement turbulence make a great "drizzled paint"
  365. *   pattern, like a 1950's counter top.
  366. *   Rule of thumb:  put a single colour transition near 0 in your colour map.
  367. *
  368. *   Mathematically, the set crackle(p)=0 is a 3D Voronoi diagram of a field of
  369. *   semirandom points, and crackle(p)>0 is distance from set along shortest path.
  370. *   (A Voronoi diagram is the locus of points equidistant from their 2 nearest
  371. *   neighbours from a set of disjoint points, like the membranes in suds are
  372. *   to the centres of the bubbles).
  373. *
  374. *   All "crackle" specific source code and examples are in the public domain.
  375. *
  376. * CHANGES
  377. *   Oct 1994    : adapted from pigment by [CY]
  378. *
  379. ******************************************************************************/
  380.  
  381. static DBL crackle (EPoint)
  382. VECTOR EPoint;
  383. {
  384.   int    i;
  385.   long   thisseed;
  386.   DBL    sum, minsum, minsum2, tf;
  387.   VECTOR sv, tv, dv, t1, add;
  388.  
  389.   static int cvc;
  390.   static long lastseed = 0x80000000;
  391.   static VECTOR cv[81];
  392.  
  393.   Assign_Vector(tv,EPoint);
  394.  
  395.   /*
  396.    * Check to see if the input point is in the same unit cube as the last
  397.    * call to this function, to use cache of cubelets for speed.
  398.    */
  399.  
  400.   thisseed = PickInCube(tv, t1);
  401.  
  402.   if (thisseed != lastseed)
  403.   {
  404.     /*
  405.      * No, not same unit cube.  Calculate the random points for this new
  406.      * cube and its 80 neighbours which differ in any axis by 1 or 2.
  407.      * Why distance of 2?  If there is 1 point in each cube, located
  408.      * randomly, it is possible for the closest random point to be in the
  409.      * cube 2 over, or the one two over and one up.  It is NOT possible
  410.      * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
  411.      * cubes glued onto each face.
  412.      */
  413.  
  414.     /* Now store a points for this cube and each of the 80 neighbour cubes. */
  415.  
  416.     cvc = 0;
  417.  
  418.     for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
  419.     {
  420.       for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
  421.       {
  422.         for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
  423.         {
  424.           /* For each cubelet in a 5x5 cube. */
  425.  
  426.           if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
  427.           {
  428.             /* Yes, it's within a 3d knight move away. */
  429.  
  430.             VAdd(sv, tv, add);
  431.  
  432.             PickInCube(sv, t1);
  433.  
  434.             cv[cvc][X] = t1[X];
  435.             cv[cvc][Y] = t1[Y];
  436.             cv[cvc][Z] = t1[Z];
  437.             cvc++;
  438.           }
  439.         }
  440.       }
  441.     }
  442.  
  443.     lastseed = thisseed;
  444.   }
  445.  
  446.   /*
  447.    * Find the 2 points with the 2 shortest distances from the input point.
  448.    * Loop invariant:  minsum is shortest dist, minsum2 is 2nd shortest
  449.    */
  450.  
  451.   /* Set up the loop so the invariant is true:  minsum <= minsum2 */
  452.  
  453.   VSub(dv, cv[0], tv);  minsum  = VSumSqr(dv);
  454.   VSub(dv, cv[1], tv);  minsum2 = VSumSqr(dv);
  455.  
  456.   if (minsum2 < minsum)
  457.   {
  458.     tf = minsum; minsum = minsum2; minsum2 = tf;
  459.   }
  460.  
  461.   /* Loop for the 81 cubelets to find closest and 2nd closest. */
  462.  
  463.   for (i = 2; i < cvc; i++)
  464.   {
  465.     VSub(dv, cv[i], tv);
  466.  
  467.     sum = VSumSqr(dv);
  468.  
  469.     if (sum < minsum)
  470.     {
  471.       minsum2 = minsum;
  472.       minsum = sum;
  473.     }
  474.     else
  475.     {
  476.       if (sum < minsum2)
  477.       {
  478.         minsum2 = sum;
  479.       }
  480.     }
  481.   }
  482.  
  483.   /* Crackle value is absolute value of diff in dist to closest 2 points. */
  484.  
  485.   tf = sqrt(minsum2) - sqrt(minsum);      /* minsum is known <= minsum2 */
  486.  
  487.   /*
  488.    * Note that the theoretical range of this function is 0 to root 3.
  489.    * In practice, it rarely exceeds 0.9, and only very rarely 1.0
  490.    */
  491.  
  492.   return min(tf, 1.);
  493. }
  494.  
  495.  
  496. /*****************************************************************************
  497. *
  498. * FUNCTION
  499. *
  500. *   gradient
  501. *
  502. * INPUT
  503. *
  504. *   EPoint -- The point in 3d space at which the pattern
  505. *   is evaluated.
  506. *   
  507. * OUTPUT
  508. *   
  509. * RETURNS
  510. *
  511. *   DBL value in the range 0.0 to 1.0
  512. *   
  513. * AUTHOR
  514. *
  515. *   POV-Ray Team
  516. *   
  517. * DESCRIPTION
  518. *
  519. *   Gradient Pattern - gradient based on the fractional values of
  520. *   x, y or z, based on whether or not the given directional vector is
  521. *   a 1.0 or a 0.0.
  522. *   The basic concept of this is from DBW Render, but Dave Wecker's
  523. *   only supports simple Y axis gradients.
  524. *
  525. * CHANGES
  526. *   Oct 1994    : adapted from pigment by [CY]
  527. *
  528. ******************************************************************************/
  529.  
  530. static DBL gradient (EPoint, TPat)
  531. VECTOR EPoint;
  532. TPATTERN *TPat;
  533. {
  534.   register int i;
  535.   register DBL temp;
  536.   DBL value = 0.0;
  537.  
  538.   for (i=X; i<=Z; i++)
  539.   {
  540.     if (TPat->Vals.Gradient[i] != 0.0)
  541.     {
  542.       temp = fabs(EPoint[i]);
  543.  
  544.       value += fmod(temp,1.0);
  545.     }
  546.   }
  547.  
  548.   /* Clamp to 1.0. */
  549.  
  550.   value = ((value > 1.0) ? fmod(value, 1.0) : value);
  551.  
  552.   return(value);
  553. }
  554.  
  555.  
  556.  
  557. /*****************************************************************************
  558. *
  559. * FUNCTION
  560. *
  561. *   granite
  562. *
  563. * INPUT
  564. *
  565. *   EPoint -- The point in 3d space at which the pattern
  566. *   is evaluated.
  567. *   
  568. * OUTPUT
  569. *   
  570. * RETURNS
  571. *
  572. *   DBL value in the range 0.0 to 1.0
  573. *   
  574. * AUTHOR
  575. *
  576. *   POV-Ray Team
  577. *   
  578. * DESCRIPTION
  579. *
  580. *   Granite - kind of a union of the "spotted" and the "dented" textures,
  581. *   using a 1/f fractal noise function for color values. Typically used
  582. *   with small scaling values. Should work with colour maps for pink granite.
  583. *
  584. * CHANGES
  585. *   Oct 1994    : adapted from pigment by [CY]
  586. *
  587. ******************************************************************************/
  588.  
  589. static DBL granite (EPoint)
  590. VECTOR EPoint;
  591. {
  592.   register int i;
  593.   register DBL temp, noise = 0.0, freq = 1.0;
  594.   VECTOR tv1,tv2;
  595.  
  596.   VScale(tv1,EPoint,4.0);
  597.  
  598.   for (i = 0; i < 6 ; freq *= 2.0, i++)
  599.   {
  600.     VScale(tv2,tv1,freq);
  601.     temp = 0.5 - Noise (tv2);
  602.  
  603.     temp = fabs(temp);
  604.  
  605.     noise += temp / freq;
  606.   }
  607.  
  608.   return(noise);
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************
  614. *
  615. * FUNCTION
  616. *
  617. *   leopard
  618. *
  619. * INPUT
  620. *
  621. *   EPoint -- The point in 3d space at which the pattern
  622. *   is evaluated.
  623. *
  624. * OUTPUT
  625. *
  626. * RETURNS
  627. *
  628. *   DBL value in the range 0.0 to 1.0
  629. *
  630. * AUTHOR
  631. *
  632. *   Scott Taylor
  633. *
  634. * DESCRIPTION
  635. *
  636. * CHANGES
  637. *   Jul 1991 : Creation.
  638. *   Oct 1994 : adapted from pigment by [CY]
  639. *
  640. ******************************************************************************/
  641.  
  642. static DBL leopard (EPoint)
  643. VECTOR EPoint;
  644. {
  645.   register DBL value, temp1, temp2, temp3;
  646.  
  647.   /* This form didn't work with Zortech 386 compiler */
  648.   /* value = Sqr((sin(x)+sin(y)+sin(z))/3); */
  649.   /* So we break it down. */
  650.  
  651.   temp1 = sin(EPoint[X]);
  652.   temp2 = sin(EPoint[Y]);
  653.   temp3 = sin(EPoint[Z]);
  654.  
  655.   value = Sqr((temp1 + temp2 + temp3) / 3.0);
  656.  
  657.   return(value);
  658. }
  659.  
  660.  
  661.  
  662. /*****************************************************************************
  663. *
  664. * FUNCTION
  665. *
  666. *   mandel
  667. *
  668. * INPUT
  669. *
  670. *   EPoint -- The point in 3d space at which the pattern
  671. *   is evaluated.
  672. *
  673. * OUTPUT
  674. *
  675. * RETURNS
  676. *
  677. *   DBL value in the range 0.0 to 1.0
  678. *
  679. * AUTHOR
  680. *
  681. *   submitted by user, name lost (sorry)
  682. *
  683. * DESCRIPTION
  684. * The mandel pattern computes the standard Mandelbrot fractal pattern and
  685. * projects it onto the X-Y plane.  It uses the X and Y coordinates to compute
  686. * the Mandelbrot set.
  687. *
  688. * CHANGES
  689. *   Oct 1994 : adapted from pigment by [CY]
  690. *
  691. ******************************************************************************/
  692.  
  693. static DBL mandel (EPoint, TPat)
  694. VECTOR EPoint;
  695. TPATTERN *TPat;
  696. {
  697.   int it_max, col;
  698.   DBL a, b, cf, a2, b2, x, y;
  699.  
  700.   a = x = EPoint[X]; a2 = Sqr(a);
  701.   b = y = EPoint[Y]; b2 = Sqr(b);
  702.  
  703.   it_max = TPat->Vals.Iterations;
  704.  
  705.   for (col = 0; col < it_max; col++)
  706.   {
  707.     b  = 2.0 * a * b + y;
  708.     a  = a2 - b2 + x;
  709.  
  710.     a2 = Sqr(a);
  711.     b2 = Sqr(b);
  712.  
  713.     if ((a2 + b2) > 4.0)
  714.     {
  715.       break;
  716.     }
  717.   }
  718.  
  719.   cf = (DBL)col / (DBL)it_max;
  720.  
  721.   return(cf);
  722. }
  723.  
  724.  
  725.  
  726. /*****************************************************************************
  727. *
  728. * FUNCTION
  729. *
  730. *   marble
  731. *
  732. * INPUT
  733. *
  734. *   EPoint -- The point in 3d space at which the pattern
  735. *   is evaluated.
  736. *   TPat   -- Texture pattern struct
  737. *
  738. * OUTPUT
  739. *
  740. * RETURNS
  741. *
  742. *   DBL value in the range 0.0 to 1.0
  743. *
  744. * AUTHOR
  745. *
  746. *   POV-Ray Team
  747. *
  748. * DESCRIPTION
  749. *
  750. * CHANGES
  751. *   Oct 1994 : adapted from pigment by [CY]
  752. *
  753. ******************************************************************************/
  754.  
  755. static DBL marble (EPoint, TPat)
  756. VECTOR EPoint;
  757. TPATTERN *TPat;
  758. {
  759.   register DBL turb_val;
  760.   TURB *Turb;
  761.  
  762.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  763.   {
  764.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  765.   }
  766.   else
  767.   {
  768.     turb_val = 0.0;
  769.   }
  770.  
  771.   return(EPoint[X] + turb_val);
  772. }
  773.  
  774.  
  775.  
  776. /*****************************************************************************
  777. *
  778. * FUNCTION
  779. *
  780. *   onion
  781. *
  782. * INPUT
  783. *
  784. *   EPoint -- The point in 3d space at which the pattern
  785. *   is evaluated.
  786. *
  787. * OUTPUT
  788. *
  789. * RETURNS
  790. *
  791. *   DBL value in the range 0.0 to 1.0
  792. *
  793. * AUTHOR
  794. *
  795. *   Scott Taylor
  796. *
  797. * DESCRIPTION
  798. *
  799. * CHANGES
  800. *   Jul 1991 : Creation.
  801. *   Oct 1994 : adapted from pigment by [CY]
  802. *
  803. ******************************************************************************/
  804.  
  805. static DBL onion (EPoint)
  806. VECTOR EPoint;
  807. {
  808.   /* The variable noise is not used as noise in this function */
  809.  
  810.   register DBL noise;
  811.  
  812. /*
  813.    This ramp goes 0-1,1-0,0-1,1-0...
  814.  
  815.    noise = (fmod(sqrt(Sqr(x)+Sqr(y)+Sqr(z)),2.0)-1.0);
  816.  
  817.    if (noise<0.0) {noise = 0.0-noise;}
  818. */
  819.  
  820.   /* This ramp goes 0-1, 0-1, 0-1, 0-1 ... */
  821.  
  822.   noise = (fmod(sqrt(Sqr(EPoint[X])+Sqr(EPoint[Y])+Sqr(EPoint[Z])), 1.0));
  823.  
  824.   return(noise);
  825. }
  826.  
  827.  
  828.  
  829. /*****************************************************************************
  830. *
  831. * FUNCTION
  832. *
  833. *   radial
  834. *
  835. * INPUT
  836. *
  837. *   EPoint -- The point in 3d space at which the pattern
  838. *   is evaluated.
  839. *
  840. * OUTPUT
  841. *
  842. * RETURNS
  843. *
  844. *   DBL value in the range 0.0 to 1.0
  845. *
  846. * AUTHOR
  847. *
  848. *   Chris Young -- new in vers 2.0
  849. *
  850. * DESCRIPTION
  851. *
  852. * CHANGES
  853. *   Oct 1994 : adapted from pigment by [CY]
  854. *
  855. ******************************************************************************/
  856.  
  857. static DBL radial (EPoint)
  858. VECTOR EPoint;
  859. {
  860.   register DBL value;
  861.  
  862.   if ((fabs(EPoint[X])<0.001) && (fabs(EPoint[Z])<0.001))
  863.   {
  864.     value = 0.25;
  865.   }
  866.   else
  867.   {
  868.     value = 0.25 + (atan2(EPoint[X],EPoint[Z]) + M_PI) / TWO_M_PI;
  869.   }
  870.  
  871.   return(value);
  872. }
  873.  
  874.  
  875.  
  876. /*****************************************************************************
  877. *
  878. * FUNCTION
  879. *
  880. *   spiral1
  881. *
  882. * INPUT
  883. *
  884. *   EPoint -- The point in 3d space at which the pattern
  885. *   is evaluated.
  886. *   TPat   -- Texture pattern struct
  887. *
  888. * OUTPUT
  889. *
  890. * RETURNS
  891. *
  892. *   DBL value in the range 0.0 to 1.0
  893. *
  894. * AUTHOR
  895. *
  896. *   Dieter Bayer
  897. *
  898. * DESCRIPTION
  899. *   Spiral whirles around z-axis.
  900. *   The number of "arms" is defined in the TPat.
  901. *
  902. * CHANGES
  903. *   Aug 1994 : Creation.
  904. *   Oct 1994 : adapted from pigment by [CY]
  905. *
  906. ******************************************************************************/
  907.  
  908. static DBL spiral1(EPoint, TPat)
  909. VECTOR EPoint;
  910. TPATTERN *TPat;
  911. {
  912.   DBL rad, phi, turb_val;
  913.   DBL x = EPoint[X];
  914.   DBL y = EPoint[Y];
  915.   DBL z = EPoint[Z];
  916.   TURB *Turb;
  917.  
  918.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  919.   {
  920.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  921.   }
  922.   else
  923.   {
  924.     turb_val = 0.0;
  925.   }
  926.  
  927.   /* Get distance from z-axis. */
  928.  
  929.   rad = sqrt(x * x + y * y);
  930.  
  931.   /* Get angle in x,y-plane (0...2 PI). */
  932.  
  933.   if (rad == 0.0)
  934.   {
  935.     phi = 0.0;
  936.   }
  937.   else
  938.   {
  939.     if (x < 0.0)
  940.     {
  941.       phi = 3.0 * M_PI_2 - asin(y / rad);
  942.     }
  943.     else
  944.     {
  945.       phi = M_PI_2 + asin(y / rad);
  946.     }
  947.   }
  948.  
  949.   return(z + rad + (DBL)TPat->Vals.Arms * phi / TWO_M_PI + turb_val);
  950. }
  951.  
  952.  
  953.  
  954. /*****************************************************************************
  955. *
  956. * FUNCTION
  957. *
  958. *   spiral2
  959. *
  960. * INPUT
  961. *
  962. *   EPoint -- The point in 3d space at which the pattern
  963. *   is evaluated.
  964. *   TPat   -- Texture pattern struct
  965. *
  966. * OUTPUT
  967. *
  968. * RETURNS
  969. *
  970. *   DBL value in the range 0.0 to 1.0
  971. *
  972. * AUTHOR
  973. *
  974. *   Dieter Bayer
  975. *
  976. * DESCRIPTION
  977. *   Spiral whirles around z-axis.
  978. *   The number of "arms" is defined in the TPat.
  979. *
  980. * CHANGES
  981. *   Aug 1994 : Creation.
  982. *   Oct 1994 : adapted from pigment by [CY]
  983. *
  984. ******************************************************************************/
  985.  
  986.  
  987. static DBL spiral2(EPoint, TPat)
  988. VECTOR EPoint;
  989. TPATTERN *TPat;
  990. {
  991.   DBL rad, phi, turb_val;
  992.   DBL x = EPoint[X];
  993.   DBL y = EPoint[Y];
  994.   DBL z = EPoint[Z];
  995.   TURB *Turb;
  996.  
  997.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  998.   {
  999.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  1000.   }
  1001.   else
  1002.   {
  1003.     turb_val = 0.0;
  1004.   }
  1005.  
  1006.   /* Get distance from z-axis. */
  1007.  
  1008.   rad = sqrt(x * x + y * y);
  1009.  
  1010.   /* Get angle in x,y-plane (0...2 PI) */
  1011.  
  1012.   if (rad == 0.0)
  1013.   {
  1014.     phi = 0.0;
  1015.   }
  1016.   else
  1017.   {
  1018.     if (x < 0.0)
  1019.     {
  1020.       phi = 3.0 * M_PI_2 - asin(y / rad);
  1021.     }
  1022.     else
  1023.     {
  1024.       phi = M_PI_2 + asin(y / rad);
  1025.     }
  1026.   }
  1027.  
  1028.   turb_val = Triangle_Wave(z + rad + (DBL)TPat->Vals.Arms * phi / TWO_M_PI +
  1029.                            turb_val);
  1030.  
  1031.   return(Triangle_Wave(rad) + turb_val);
  1032. }
  1033.  
  1034.  
  1035.  
  1036. /*****************************************************************************
  1037. *
  1038. * FUNCTION
  1039. *
  1040. *   wood
  1041. *
  1042. * INPUT
  1043. *
  1044. *   EPoint -- The point in 3d space at which the pattern
  1045. *   is evaluated.
  1046. *   TPat   -- Texture pattern struct
  1047. *
  1048. * OUTPUT
  1049. *
  1050. * RETURNS
  1051. *
  1052. *   DBL value in the range 0.0 to 1.0
  1053. *
  1054. * AUTHOR
  1055. *
  1056. *   POV-Ray Team
  1057. *
  1058. * DESCRIPTION
  1059. *
  1060. * CHANGES
  1061. *   Oct 1994 : adapted from pigment by [CY]
  1062. *
  1063. ******************************************************************************/
  1064.  
  1065.  
  1066. static DBL wood (EPoint, TPat)
  1067. VECTOR EPoint;
  1068. TPATTERN *TPat;
  1069. {
  1070.   register DBL length;
  1071.   VECTOR WoodTurbulence;
  1072.   VECTOR point;
  1073.   DBL x=EPoint[X];
  1074.   DBL y=EPoint[Y];
  1075.   TURB *Turb;
  1076.  
  1077.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  1078.   {
  1079.     DTurbulence (WoodTurbulence, EPoint,Turb);
  1080.     point[X] = cycloidal((x + WoodTurbulence[X]) * Turb->Turbulence[X]);
  1081.     point[Y] = cycloidal((y + WoodTurbulence[Y]) * Turb->Turbulence[Y]);
  1082.   }
  1083.   else
  1084.   {
  1085.     point[X] = 0.0;
  1086.     point[Y] = 0.0;
  1087.   }
  1088.   point[Z] = 0.0;
  1089.  
  1090.   point[X] += x;
  1091.   point[Y] += y;
  1092.  
  1093.   /* point[Z] += z; Deleted per David Buck --  BP 7/91 */
  1094.  
  1095.   VLength (length, point);
  1096.  
  1097.   return(length);
  1098. }
  1099.  
  1100.  
  1101. /*****************************************************************************
  1102. *
  1103. * FUNCTION
  1104. *
  1105. *   hexagon
  1106. *
  1107. * INPUT
  1108. *
  1109. *   EPoint -- The point in 3d space at which the pattern
  1110. *   is evaluated.
  1111. *
  1112. * OUTPUT
  1113. *
  1114. * RETURNS
  1115. *
  1116. *   DBL value exactly 0.0, 1.0 or 2.0
  1117. *
  1118. * AUTHOR
  1119. *
  1120. *   Ernest MacDougal Campbell III
  1121. *   
  1122. * DESCRIPTION
  1123. *
  1124. *   TriHex pattern -- Ernest MacDougal Campbell III (EMC3) 11/23/92
  1125. *
  1126. *   Creates a hexagon pattern in the XZ plane.
  1127. *
  1128. *   This algorithm is hard to explain.  First it scales the point to make
  1129. *   a few of the later calculations easier, then maps some points to be
  1130. *   closer to the Origin.  A small area in the first quadrant is subdivided
  1131. *   into a 6 x 6 grid.  The position of the point mapped into that grid
  1132. *   determines its color.  For some points, just the grid location is enough,
  1133. *   but for others, we have to calculate which half of the block it's in
  1134. *   (this is where the atan2() function comes in handy).
  1135. *
  1136. * CHANGES
  1137. *   Nov 1992 : Creation.
  1138. *   Oct 1994 : adapted from pigment by [CY]
  1139. *
  1140. ******************************************************************************/
  1141.  
  1142. #define xfactor 0.5;         /* each triangle is split in half for the grid */
  1143. #define zfactor 0.866025404; /* sqrt(3)/2 -- Height of an equilateral triangle */
  1144.  
  1145. static DBL hexagon (EPoint)
  1146. VECTOR EPoint;
  1147. {
  1148.   int xm, zm;
  1149.   int brkindx;
  1150.   DBL xs, zs, xl, zl, value = 0.0;
  1151.   DBL x=EPoint[X];
  1152.   DBL z=EPoint[Z];
  1153.  
  1154.  
  1155.   /* Keep all numbers positive.  Also, if z is negative, map it in such a
  1156.    * way as to avoid mirroring across the x-axis.  The value 5.196152424
  1157.    * is (sqrt(3)/2) * 6 (because the grid is 6 blocks high)
  1158.    */
  1159.  
  1160.   x = fabs(x);
  1161.  
  1162.   /* Avoid mirroring across x-axis. */
  1163.  
  1164.   z = z < 0.0 ? 5.196152424 - fabs(z) : z;
  1165.  
  1166.   /* Scale point to make calcs easier. */
  1167.  
  1168.   xs = x/xfactor;
  1169.   zs = z/zfactor;
  1170.  
  1171.   /* Map points into the 6 x 6 grid where the basic formula works. */
  1172.  
  1173.   xs -= floor(xs/6.0) * 6.0;
  1174.   zs -= floor(zs/6.0) * 6.0;
  1175.  
  1176.   /* Get a block in the 6 x 6 grid. */
  1177.  
  1178.   xm = (int) FLOOR(xs) % 6;
  1179.   zm = (int) FLOOR(zs) % 6;
  1180.  
  1181.   switch (xm)
  1182.   {
  1183.     /* These are easy cases: Color depends only on xm and zm. */
  1184.  
  1185.     case 0:
  1186.     case 5:
  1187.  
  1188.       switch (zm)
  1189.       {
  1190.         case 0:
  1191.         case 5: value = 0; break;
  1192.  
  1193.         case 1:
  1194.         case 2: value = 1; break;
  1195.  
  1196.         case 3:
  1197.         case 4: value = 2; break;
  1198.       }
  1199.  
  1200.       break;
  1201.  
  1202.     case 2:
  1203.     case 3:
  1204.  
  1205.       switch (zm)
  1206.       {
  1207.         case 0:
  1208.         case 1: value = 2; break;
  1209.  
  1210.         case 2:
  1211.         case 3: value = 0; break;
  1212.  
  1213.         case 4:
  1214.         case 5: value = 1; break;
  1215.       }
  1216.  
  1217.       break;
  1218.  
  1219.     /* These cases are harder.  These blocks are divided diagonally
  1220.      * by the angled edges of the hexagons.  Some slope positive, and
  1221.      * others negative.  We flip the x value of the negatively sloped
  1222.      * pieces.  Then we check to see if the point in question falls
  1223.      * in the upper or lower half of the block.  That info, plus the
  1224.      * z status of the block determines the color.
  1225.      */
  1226.  
  1227.     case 1:
  1228.     case 4:
  1229.  
  1230.       /* Map the point into the block at the origin. */
  1231.  
  1232.       xl = xs-xm;
  1233.       zl = zs-zm;
  1234.  
  1235.       /* These blocks have negative slopes so we flip it horizontally. */
  1236.  
  1237.       if (((xm + zm) % 2) == 1)
  1238.       {
  1239.         xl = 1.0 - xl;
  1240.       }
  1241.  
  1242.       /* Avoid a divide-by-zero error. */
  1243.  
  1244.       if (xl == 0.0)
  1245.       {
  1246.         xl = 0.0001;
  1247.       }
  1248.  
  1249.       /* Is the angle less-than or greater-than 45 degrees? */
  1250.  
  1251.       brkindx = (zl / xl) < 1.0;
  1252.  
  1253.       /* was...
  1254.        * brkindx = (atan2(zl,xl) < (45 * M_PI_180));
  1255.        * ...but because of the mapping, it's easier and cheaper,
  1256.        * CPU-wise, to just use a good ol' slope.
  1257.        */
  1258.  
  1259.       switch (brkindx)
  1260.       {
  1261.         case TRUE:
  1262.  
  1263.           switch (zm)
  1264.           {
  1265.             case 0:
  1266.             case 3: value = 0; break;
  1267.  
  1268.             case 2:
  1269.             case 5: value = 1; break;
  1270.  
  1271.             case 1:
  1272.             case 4: value = 2; break;
  1273.           }
  1274.  
  1275.           break;
  1276.  
  1277.         case FALSE:
  1278.  
  1279.           switch (zm)
  1280.           {
  1281.             case 0:
  1282.             case 3: value = 2; break;
  1283.  
  1284.             case 2:
  1285.             case 5: value = 0; break;
  1286.  
  1287.             case 1:
  1288.             case 4: value = 1; break;
  1289.           }
  1290.  
  1291.           break;
  1292.       }
  1293.   }
  1294.  
  1295.   value = fmod(value, 3.0);
  1296.  
  1297.   return(value);
  1298. }
  1299.  
  1300.  
  1301.  
  1302. /*****************************************************************************
  1303. *
  1304. * FUNCTION
  1305. *
  1306. *   PickInCube(tv, p1)
  1307. *
  1308. * INPUT
  1309. *
  1310. *   ?
  1311. *
  1312. * OUTPUT
  1313. *   
  1314. * RETURNS
  1315. *
  1316. *   long integer hash function used, to speed up cacheing.
  1317. *   
  1318. * AUTHOR
  1319. *
  1320. *   Jim McElhiney
  1321. *   
  1322. * DESCRIPTION
  1323. *
  1324. *   A subroutine to go with crackle.
  1325. *
  1326. *   Pick a random point in the same unit-sized cube as tv, in a
  1327. *   predictable way, so that when called again with another point in
  1328. *   the same unit cube, p1 is picked to be the same.
  1329. *
  1330. * CHANGES
  1331. *
  1332. ******************************************************************************/
  1333.  
  1334. static long PickInCube(tv, p1)
  1335. VECTOR tv, p1;
  1336. {
  1337.   int seed;
  1338.   VECTOR flo;
  1339.  
  1340.   /*
  1341.    * This uses floor() not FLOOR, so it will not be a mirror
  1342.    * image about zero in the range -1.0 to 1.0. The viewer
  1343.    * won't see an artefact around the origin.
  1344.    */
  1345.  
  1346.   flo[X] = floor(tv[X] - EPSILON);
  1347.   flo[Y] = floor(tv[Y] - EPSILON);
  1348.   flo[Z] = floor(tv[Z] - EPSILON);
  1349.  
  1350.   seed = Hash3d((int)flo[X], (int)flo[Y], (int)flo[Z]);
  1351.  
  1352.   POV_SRAND(seed);
  1353.  
  1354.   p1[X] = flo[X] + FRAND();
  1355.   p1[Y] = flo[Y] + FRAND();
  1356.   p1[Z] = flo[Z] + FRAND();
  1357.  
  1358.   return((long)seed);
  1359. }
  1360.  
  1361.  
  1362.  
  1363. /*****************************************************************************
  1364. *
  1365. * FUNCTION
  1366. *
  1367. *   Evaluate_Pattern
  1368. *
  1369. * INPUT
  1370. *
  1371. *   EPoint -- The point in 3d space at which the pattern
  1372. *   is evaluated.
  1373. *   TPat   -- Texture pattern struct
  1374. *   
  1375. * OUTPUT
  1376. *   
  1377. * RETURNS
  1378. *
  1379. *   DBL result usual 0.0 to 1.0 but may be 2.0 in hexagon
  1380. *   
  1381. * AUTHOR
  1382. *
  1383. *   adapted from Add_Pigment by Chris Young
  1384. *   
  1385. * DESCRIPTION
  1386. *
  1387. * CHANGES
  1388. *
  1389. ******************************************************************************/
  1390.  
  1391. DBL Evaluate_TPat (TPat, EPoint)
  1392. TPATTERN *TPat;
  1393. VECTOR EPoint;
  1394. {
  1395.   DBL value = 0.0;
  1396.   VECTOR TPoint;
  1397.  
  1398.   Warp_EPoint (TPoint, EPoint, TPat);
  1399.  
  1400.   switch (TPat->Type)
  1401.   {
  1402.     case AGATE_PATTERN:    value = agate    (TPoint, TPat);   break;
  1403.  
  1404.     case BOZO_PATTERN:
  1405.     case SPOTTED_PATTERN:
  1406.     case BUMPS_PATTERN:    value = Noise    (TPoint);         break;
  1407.  
  1408.     case BRICK_PATTERN:    value = brick    (TPoint, TPat);   break;
  1409.     case CHECKER_PATTERN:  value = checker  (TPoint);         break;
  1410.     case CRACKLE_PATTERN:  value = crackle  (TPoint);         break;
  1411.     case GRADIENT_PATTERN: value = gradient (TPoint, TPat);   break;
  1412.     case GRANITE_PATTERN:  value = granite  (TPoint);         break;
  1413.     case HEXAGON_PATTERN:  value = hexagon  (TPoint);         break;
  1414.     case LEOPARD_PATTERN:  value = leopard  (TPoint);         break;
  1415.     case MANDEL_PATTERN:   value = mandel   (TPoint, TPat);   break;
  1416.     case MARBLE_PATTERN:   value = marble   (TPoint, TPat);   break;
  1417.     case ONION_PATTERN:    value = onion    (TPoint);         break;
  1418.     case RADIAL_PATTERN:   value = radial   (TPoint);         break;
  1419.     case SPIRAL1_PATTERN:  value = spiral1  (TPoint, TPat);   break;
  1420.     case SPIRAL2_PATTERN:  value = spiral2  (TPoint, TPat);   break;
  1421.     case PATTERN1_PATTERN: value = pattern1    (TPoint, TPat);   break;
  1422.     case PATTERN2_PATTERN: value = pattern2    (TPoint, TPat);   break;
  1423.     case PATTERN3_PATTERN: value = pattern3    (TPoint, TPat);   break;
  1424.     case WOOD_PATTERN:     value = wood     (TPoint, TPat);   break;
  1425.  
  1426.     case WAVES_PATTERN:    value = waves_pigm    (TPoint, TPat);   break;
  1427.     case RIPPLES_PATTERN:  value = ripples_pigm  (TPoint, TPat);   break;
  1428.     case WRINKLES_PATTERN: value = wrinkles_pigm (TPoint);   break;
  1429.     case DENTS_PATTERN:    value = dents_pigm    (TPoint);   break;
  1430.     case QUILTED_PATTERN:  value = quilted_pigm  (TPoint, TPat);   break;
  1431.     default: Error("Problem in Evaluate_TPat.");
  1432.   }
  1433.  
  1434.   if (TPat->Frequency !=0.0)
  1435.   {
  1436.     value = fmod(value * TPat->Frequency + TPat->Phase, 1.00001);
  1437.   }
  1438.  
  1439.   /* allow negative Frequency */
  1440.  
  1441.   if (value < 0.0)
  1442.   {
  1443.     value -= floor(value);
  1444.   }
  1445.  
  1446.   switch (TPat->Wave_Type)
  1447.   {
  1448.     case RAMP_WAVE:
  1449.       break;
  1450.  
  1451.     case SINE_WAVE:
  1452.       value = (1.0+cycloidal(value))*0.5;
  1453.       break;
  1454.  
  1455.     case TRIANGLE_WAVE:
  1456.       value = Triangle_Wave(value);
  1457.       break;
  1458.  
  1459.     case SCALLOP_WAVE:
  1460.       value = fabs(cycloidal(value*0.5));
  1461.       break;
  1462.  
  1463.     default: Error("Unknown Wave Type %d.",TPat->Wave_Type);
  1464.    }
  1465.  
  1466.   return(value);
  1467. }
  1468.  
  1469.  
  1470. /*****************************************************************************
  1471. *
  1472. * FUNCTION
  1473. *
  1474. * INPUT
  1475. *
  1476. * OUTPUT
  1477. *
  1478. * RETURNS
  1479. *
  1480. * AUTHOR
  1481. *
  1482. * DESCRIPTION
  1483. *
  1484. * CHANGES
  1485. *
  1486. ******************************************************************************/
  1487.  
  1488. void Init_TPat_Fields (Tpat)
  1489. TPATTERN *Tpat;
  1490. {
  1491.   Tpat->Type       = NO_PATTERN;
  1492.   Tpat->Wave_Type  = RAMP_WAVE;
  1493.   Tpat->Flags      = NO_FLAGS;
  1494.   Tpat->References = 1;
  1495.   Tpat->Frequency  = 1.0;
  1496.   Tpat->Phase      = 0.0;
  1497.   Tpat->Warps      = NULL;
  1498.   Tpat->Next       = NULL;
  1499.   Tpat->Blend_Map  = NULL;
  1500. }
  1501.  
  1502.  
  1503.  
  1504. /*****************************************************************************
  1505. *
  1506. * FUNCTION
  1507. *
  1508. * INPUT
  1509. *
  1510. * OUTPUT
  1511. *
  1512. * RETURNS
  1513. *
  1514. * AUTHOR
  1515. *
  1516. * DESCRIPTION
  1517. *
  1518. * CHANGES
  1519. *
  1520. ******************************************************************************/
  1521.  
  1522. void Copy_TPat_Fields (New, Old)
  1523. TPATTERN *New, *Old;
  1524. {
  1525.   *New = *Old;
  1526.   
  1527.   /* Copy warp chain */
  1528.   New->Warps = Copy_Warps(Old->Warps);
  1529.  
  1530.   New->Blend_Map = Copy_Blend_Map(Old->Blend_Map);
  1531.  
  1532.   /* Note, cannot copy Old->Next because we don't know what kind of
  1533.      thing this is.  It must be copied by Copy_Pigment, Copy_Tnormal etc.
  1534.   */
  1535.  
  1536.   if (Old->Type == BITMAP_PATTERN)
  1537.   {
  1538.      New->Vals.Image = Copy_Image(Old->Vals.Image);
  1539.   }
  1540. }
  1541.  
  1542.  
  1543.  
  1544. /*****************************************************************************
  1545. *
  1546. * FUNCTION
  1547. *
  1548. * INPUT
  1549. *
  1550. * OUTPUT
  1551. *
  1552. * RETURNS
  1553. *
  1554. * AUTHOR
  1555. *
  1556. * DESCRIPTION
  1557. *
  1558. * CHANGES
  1559. *
  1560. ******************************************************************************/
  1561.  
  1562. void Destroy_TPat_Fields(Tpat)
  1563. TPATTERN *Tpat;
  1564. {
  1565.   Destroy_Warps(Tpat->Warps);
  1566.   Destroy_Blend_Map(Tpat->Blend_Map);
  1567.   /* Note, cannot destroy Tpat->Next nor pattern itself because we don't
  1568.      know what kind of thing this is.  It must be destroied by Destroy_Pigment, etc.
  1569.   */
  1570.  
  1571.   if (Tpat->Type == BITMAP_PATTERN)
  1572.   {
  1573.      Destroy_Image(Tpat->Vals.Image);
  1574.   }
  1575. }
  1576.  
  1577.  
  1578.  
  1579.  
  1580. /*****************************************************************************
  1581. *
  1582. * FUNCTION
  1583. *
  1584. * INPUT
  1585. *
  1586. * OUTPUT
  1587. *
  1588. * RETURNS
  1589. *
  1590. * AUTHOR
  1591. *
  1592. * DESCRIPTION
  1593. *
  1594. * CHANGES
  1595. *
  1596. ******************************************************************************/
  1597.  
  1598. TURB *Create_Turb()
  1599. {
  1600.   TURB *New;
  1601.  
  1602.   New = POV_MALLOC(sizeof(TURB),"turbulence struct");
  1603.  
  1604.   Make_Vector(New->Turbulence, 0.0, 0.0, 0.0);
  1605.  
  1606.   New->Octaves = 6;
  1607.   New->Omega = 0.5;
  1608.   New->Lambda = 2.0;
  1609.  
  1610.   return(New);
  1611. }
  1612.  
  1613.  
  1614.  
  1615. /*****************************************************************************
  1616. *
  1617. * FUNCTION
  1618. *
  1619. * INPUT
  1620. *
  1621. * OUTPUT
  1622. *
  1623. * RETURNS
  1624. *
  1625. * AUTHOR
  1626. *
  1627. * DESCRIPTION
  1628. *
  1629. * CHANGES
  1630. *
  1631. ******************************************************************************/
  1632.  
  1633. #if 0   /* Unused function [AED] */
  1634. static TURB *Copy_Turb(Old)
  1635. TURB *Old;
  1636. {
  1637.   TURB *New;
  1638.  
  1639.   if (Old != NULL)
  1640.   {
  1641.     New = Create_Turb();
  1642.  
  1643.     *New = *Old;
  1644.   }
  1645.   else
  1646.   {
  1647.     New=NULL;
  1648.   }
  1649.  
  1650.   return(New);
  1651. }
  1652. #endif
  1653.  
  1654.  
  1655. /*****************************************************************************
  1656. *
  1657. * FUNCTION
  1658. *
  1659. *   Translate_Tpattern
  1660. *
  1661. * INPUT
  1662. *
  1663. * OUTPUT
  1664. *
  1665. * RETURNS
  1666. *
  1667. * AUTHOR
  1668. *
  1669. *   POV-Ray Team
  1670. *
  1671. * DESCRIPTION
  1672. *
  1673. * CHANGES
  1674. *
  1675. ******************************************************************************/
  1676.  
  1677. void Translate_Tpattern(Tpattern,Vector)
  1678. TPATTERN *Tpattern;
  1679. VECTOR Vector;
  1680. {
  1681.   TRANSFORM Trans;
  1682.  
  1683.   if (Tpattern != NULL)
  1684.   {
  1685.     Compute_Translation_Transform (&Trans, Vector);
  1686.  
  1687.     Transform_Tpattern (Tpattern, &Trans);
  1688.   }
  1689. }
  1690.  
  1691.  
  1692.  
  1693. /*****************************************************************************
  1694. *
  1695. * FUNCTION
  1696. *
  1697. *   Rotate_Tpattern
  1698. *
  1699. * INPUT
  1700. *
  1701. * OUTPUT
  1702. *
  1703. * RETURNS
  1704. *
  1705. * AUTHOR
  1706. *
  1707. *   POV-Ray Team
  1708. *
  1709. * DESCRIPTION
  1710. *
  1711. * CHANGES
  1712. *
  1713. ******************************************************************************/
  1714.  
  1715. void Rotate_Tpattern(Tpattern,Vector)
  1716. TPATTERN *Tpattern;
  1717. VECTOR Vector;
  1718. {
  1719.   TRANSFORM Trans;
  1720.  
  1721.   if (Tpattern != NULL)
  1722.   {
  1723.     Compute_Rotation_Transform (&Trans, Vector);
  1724.  
  1725.     Transform_Tpattern (Tpattern, &Trans);
  1726.   }
  1727. }
  1728.  
  1729.  
  1730.  
  1731. /*****************************************************************************
  1732. *
  1733. * FUNCTION
  1734. *
  1735. *   Scale_Tpattern
  1736. *
  1737. * INPUT
  1738. *
  1739. * OUTPUT
  1740. *
  1741. * RETURNS
  1742. *
  1743. * AUTHOR
  1744. *
  1745. *   POV-Ray Team
  1746. *
  1747. * DESCRIPTION
  1748. *
  1749. * CHANGES
  1750. *
  1751. ******************************************************************************/
  1752.  
  1753. void Scale_Tpattern(Tpattern,Vector)
  1754. TPATTERN *Tpattern;
  1755. VECTOR Vector;
  1756. {
  1757.   TRANSFORM Trans;
  1758.  
  1759.   if (Tpattern != NULL)
  1760.   {
  1761.     Compute_Scaling_Transform (&Trans, Vector);
  1762.  
  1763.     Transform_Tpattern (Tpattern, &Trans);
  1764.   }
  1765. }
  1766.  
  1767.  
  1768.  
  1769. /*****************************************************************************
  1770. *
  1771. * FUNCTION
  1772. *
  1773. *   Transform_Tpattern
  1774. *
  1775. * INPUT
  1776. *
  1777. * OUTPUT
  1778. *
  1779. * RETURNS
  1780. *
  1781. * AUTHOR
  1782. *
  1783. *   POV-Ray Team
  1784. *
  1785. * DESCRIPTION
  1786. *
  1787. * CHANGES
  1788. *
  1789. ******************************************************************************/
  1790.  
  1791. void Transform_Tpattern(Tpattern,Trans)
  1792. TPATTERN *Tpattern;
  1793. TRANSFORM *Trans;
  1794. {
  1795.   WARP *Temp;
  1796.  
  1797.   if (Tpattern != NULL)
  1798.   {
  1799.     if (Tpattern->Warps == NULL)
  1800.     {
  1801.       Tpattern->Warps=Create_Warp(TRANSFORM_WARP);
  1802.     }
  1803.     else
  1804.     {
  1805.       if (Tpattern->Warps->Warp_Type != TRANSFORM_WARP)
  1806.       {
  1807.         Temp=Tpattern->Warps;
  1808.  
  1809.         Tpattern->Warps=Create_Warp(TRANSFORM_WARP);
  1810.  
  1811.         Tpattern->Warps->Next_Warp=Temp;
  1812.       }
  1813.     }
  1814.  
  1815.     Compose_Transforms (&( ((TRANS *)(Tpattern->Warps))->Trans), Trans);
  1816.   }
  1817. }
  1818.  
  1819.  
  1820. /*****************************************************************************
  1821. *
  1822. * FUNCTION
  1823. *
  1824. *   ripples_pigm
  1825. *
  1826. * INPUT
  1827. *
  1828. *   EPoint -- The point in 3d space at which the pattern
  1829. *   is evaluated.
  1830. *   TPat   -- Texture pattern struct
  1831. *
  1832. * OUTPUT
  1833. *   
  1834. * RETURNS
  1835. *
  1836. *   DBL value in the range 0.0 to 1.0
  1837. *   
  1838. * AUTHOR
  1839. *
  1840. *   POV-Ray Team
  1841. *
  1842. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1843. *                 Normals have a specialized pattern for this.
  1844. *
  1845. * CHANGES
  1846. *   Nov 1994 : adapted from normal by [CY]
  1847. *
  1848. ******************************************************************************/
  1849.  
  1850. static DBL ripples_pigm (EPoint, TPat)
  1851. VECTOR EPoint;
  1852. TPATTERN *TPat;
  1853. {
  1854.   register unsigned int i;
  1855.   register DBL length, index;
  1856.   DBL scalar =0.0;
  1857.   VECTOR point;
  1858.  
  1859.   for (i = 0 ; i < Number_Of_Waves ; i++)
  1860.   {
  1861.     VSub (point, EPoint, Wave_Sources[i]);
  1862.     VLength (length, point);
  1863.  
  1864.     if (length == 0.0)
  1865.       length = 1.0;
  1866.  
  1867.     index = length * TPat->Frequency + TPat->Phase;
  1868.  
  1869.     scalar += cycloidal(index);
  1870.   }
  1871.  
  1872.   scalar = 0.5*(1.0+(scalar / (DBL)Number_Of_Waves));
  1873.  
  1874.   return(scalar);
  1875. }
  1876.  
  1877.  
  1878. /*****************************************************************************
  1879. *
  1880. * FUNCTION
  1881. *
  1882. *   waves_pigm
  1883. *
  1884. * INPUT
  1885. *
  1886. *   EPoint -- The point in 3d space at which the pattern
  1887. *   is evaluated.
  1888. *   TPat   -- Texture pattern struct
  1889. *
  1890. * OUTPUT
  1891. *
  1892. * RETURNS
  1893. *
  1894. *   DBL value in the range 0.0 to 1.0
  1895. *
  1896. * AUTHOR
  1897. *
  1898. *   POV-Ray Team
  1899. *
  1900. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1901. *                 Normals have a specialized pattern for this.
  1902. *
  1903. * CHANGES
  1904. *   Nov 1994 : adapted from normal by [CY]
  1905. *
  1906. ******************************************************************************/
  1907.  
  1908. static DBL waves_pigm (EPoint, TPat)
  1909. VECTOR EPoint;
  1910. TPATTERN *TPat;
  1911. {
  1912.   register unsigned int i;
  1913.   register DBL length, index;
  1914.   DBL scalar = 0.0;
  1915.   VECTOR point;
  1916.  
  1917.   for (i = 0 ; i < Number_Of_Waves ; i++)
  1918.   {
  1919.     VSub (point, EPoint, Wave_Sources[i]);
  1920.     VLength (length, point);
  1921.  
  1922.     if (length == 0.0)
  1923.     {
  1924.       length = 1.0;
  1925.     }
  1926.  
  1927.     index = length * TPat->Frequency * frequency[i] + TPat->Phase;
  1928.  
  1929.     scalar += cycloidal(index)/frequency[i];
  1930.   }
  1931.  
  1932.   scalar = 0.2*(2.5+(scalar / (DBL)Number_Of_Waves));
  1933.  
  1934.   return(scalar);
  1935. }
  1936.  
  1937.  
  1938. /*****************************************************************************
  1939. *
  1940. * FUNCTION
  1941. *
  1942. *   dents_pigm
  1943. *
  1944. * INPUT
  1945. *
  1946. *   EPoint -- The point in 3d space at which the pattern
  1947. *   is evaluated.
  1948. *
  1949. * OUTPUT
  1950. *
  1951. * RETURNS
  1952. *
  1953. *   DBL value in the range 0.0 to 1.0
  1954. *   
  1955. * AUTHOR
  1956. *
  1957. *   POV-Ray Team
  1958. *   
  1959. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1960. *                 Normals have a specialized pattern for this.
  1961. *
  1962. * CHANGES
  1963. *   Nov 1994 : adapted from normal by [CY]
  1964. *
  1965. ******************************************************************************/
  1966.  
  1967. static DBL dents_pigm (EPoint)
  1968. VECTOR EPoint;
  1969. {
  1970.   DBL noise;
  1971.  
  1972.   noise = Noise (EPoint);
  1973.  
  1974.   return(noise * noise * noise);
  1975. }
  1976.  
  1977.  
  1978.  
  1979. /*****************************************************************************
  1980. *
  1981. * FUNCTION
  1982. *
  1983. *   wrinkles_pigm
  1984. *
  1985. * INPUT
  1986. *
  1987. *   EPoint -- The point in 3d space at which the pattern
  1988. *   is evaluated.
  1989. *   
  1990. * OUTPUT
  1991. *   
  1992. * RETURNS
  1993. *
  1994. *   DBL value in the range 0.0 to 1.0
  1995. *   
  1996. * AUTHOR
  1997. *
  1998. *   POV-Ray Team
  1999. *   
  2000. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  2001. *                 Normals have a specialized pattern for this.
  2002. *
  2003. * CHANGES
  2004. *   Nov 1994 : adapted from normal by [CY]
  2005. *
  2006. ******************************************************************************/
  2007.  
  2008.  
  2009. static DBL wrinkles_pigm (EPoint)
  2010. VECTOR EPoint;
  2011. {
  2012.   register int i;
  2013.   DBL lambda = 2.0;
  2014.   DBL omega = 0.5;
  2015.   DBL value;
  2016.   VECTOR temp;
  2017.  
  2018.   value = Noise(EPoint);
  2019.  
  2020.   for (i = 1; i < 10; i++)
  2021.   {
  2022.     VScale(temp,EPoint,lambda);
  2023.  
  2024.     value += omega * Noise(temp);
  2025.  
  2026.     lambda *= 2.0;
  2027.  
  2028.     omega *= 0.5;
  2029.   }
  2030.  
  2031.   return(value/2.0);
  2032. }
  2033.  
  2034.  
  2035.  
  2036. /*****************************************************************************
  2037. *
  2038. * FUNCTION
  2039. *
  2040. *   quilted_pigm
  2041. *
  2042. * INPUT
  2043. *   
  2044. * OUTPUT
  2045. *   
  2046. * RETURNS
  2047. *   
  2048. * AUTHOR
  2049. *
  2050. *   Dan Farmer & Chris Young
  2051. *   
  2052. * DESCRIPTION
  2053. *
  2054. * CHANGES
  2055. *
  2056. ******************************************************************************/
  2057.  
  2058. static DBL quilted_pigm (EPoint, TPat)
  2059. VECTOR EPoint;
  2060. TPATTERN *TPat;
  2061. {
  2062.   VECTOR value;
  2063.   DBL t;
  2064.  
  2065.   value[X] = EPoint[X]-FLOOR(EPoint[X])-0.5;
  2066.   value[Y] = EPoint[Y]-FLOOR(EPoint[Y])-0.5;
  2067.   value[Z] = EPoint[Z]-FLOOR(EPoint[Z])-0.5;
  2068.  
  2069.   t = sqrt(value[X]*value[X]+value[Y]*value[Y]+value[Z]*value[Z]);
  2070.  
  2071.   t = quilt_cubic(t, TPat->Vals.Quilted.Control0, TPat->Vals.Quilted.Control1);
  2072.  
  2073.   value[X] *= t;
  2074.   value[Y] *= t;
  2075.   value[Z] *= t;
  2076.  
  2077.   return((fabs(value[X])+fabs(value[Y])+fabs(value[Z]))/3.0);
  2078. }
  2079.  
  2080.  
  2081.  
  2082. /*****************************************************************************
  2083. *
  2084. * FUNCTION
  2085. *
  2086. * INPUT
  2087. *
  2088. * OUTPUT
  2089. *
  2090. * RETURNS
  2091. *
  2092. * AUTHOR
  2093. *
  2094. * DESCRIPTION
  2095. *
  2096. * CHANGES
  2097. *
  2098. ******************************************************************************/
  2099.  
  2100. #define INV_SQRT_3_4 1.154700538
  2101. DBL quilt_cubic(t,p1,p2)
  2102. DBL t,p1,p2;
  2103. {
  2104.  DBL it=(1-t);
  2105.  DBL itsqrd=it*it;
  2106. /* DBL itcubed=it*itsqrd; */
  2107.  DBL tsqrd=t*t;
  2108.  DBL tcubed=t*tsqrd;
  2109.  DBL val;
  2110.  
  2111. /* Originally coded as...
  2112.  
  2113.  val= (DBL)(itcubed*n1+(tcubed)*n2+3*t*(itsqrd)*p1+3*(tsqrd)*(it)*p2);
  2114.  
  2115.  re-written by CEY to optimise because n1=0 n2=1 always.
  2116.  
  2117. */
  2118.  
  2119.  val = (tcubed + 3.0*t*itsqrd*p1 + 3.0*tsqrd*it*p2) * INV_SQRT_3_4;
  2120.  
  2121.  return(val);
  2122. }
  2123.  
  2124.  
  2125.  
  2126. /*****************************************************************************
  2127. *
  2128. * FUNCTION
  2129. *
  2130. * INPUT
  2131. *
  2132. * OUTPUT
  2133. *
  2134. * RETURNS
  2135. *
  2136. * AUTHOR
  2137. *
  2138. * DESCRIPTION
  2139. *
  2140. * CHANGES
  2141. *
  2142. ******************************************************************************/
  2143.  
  2144. void Search_Blend_Map (value,Blend_Map,Prev,Cur)
  2145. DBL value;
  2146. BLEND_MAP *Blend_Map;
  2147. BLEND_MAP_ENTRY **Prev, **Cur;
  2148. {
  2149.   BLEND_MAP_ENTRY *P, *C;
  2150.   int Max_Ent=Blend_Map->Number_Of_Entries-1;
  2151.  
  2152.   /* if greater than last, use last. */
  2153.  
  2154.   if (value >= Blend_Map->Blend_Map_Entries[Max_Ent].value)
  2155.   {
  2156.     P = C = &(Blend_Map->Blend_Map_Entries[Max_Ent]);
  2157.   }
  2158.   else
  2159.   {
  2160.     P = C = &(Blend_Map->Blend_Map_Entries[0]);
  2161.  
  2162.     while (value > C->value)
  2163.     {
  2164.       P = C++;
  2165.     }
  2166.   }
  2167.  
  2168.   if (value == C->value)
  2169.   {
  2170.     P = C;
  2171.   }
  2172.  
  2173.   *Prev = P;
  2174.   *Cur  = C;
  2175. }
  2176.  
  2177.  
  2178.  
  2179. /*****************************************************************************
  2180. *
  2181. * FUNCTION
  2182. *
  2183. * INPUT
  2184. *
  2185. * OUTPUT
  2186. *
  2187. * RETURNS
  2188. *
  2189. * AUTHOR
  2190. *
  2191. * DESCRIPTION
  2192. *
  2193. * CHANGES
  2194. *
  2195. ******************************************************************************/
  2196.  
  2197. static TURB *Search_For_Turb(Warps)
  2198. WARP *Warps;
  2199. {
  2200.   WARP* Temp=Warps;
  2201.  
  2202.   if (Temp!=NULL)
  2203.   {
  2204.     while (Temp->Next_Warp != NULL)
  2205.     {
  2206.       Temp=Temp->Next_Warp;
  2207.     }
  2208.  
  2209.     if (Temp->Warp_Type != CLASSIC_TURB_WARP)
  2210.     {
  2211.        Temp=NULL;
  2212.     }
  2213.   }
  2214.  
  2215.   return ((TURB *)Temp);
  2216. }
  2217.